package com.goldsign.pay.common.util;


import com.goldsign.pay.common.string.StringUtil;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/** 日期处理助手类 */
public class DateUtil {
	private static DateFormat dfDatetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private static DateFormat dfDate = new SimpleDateFormat("yyyy-MM-dd");
	
	/**短日期格式,yyyy-MM-dd*/
	public final static int SHORT_DATEFORMAT = 1;
	/**长日期格式,yyyy-MM-dd HH:mm:ss*/
	public final static int LONG_DATEFORMAT = 2;
	/**短日期中文格式,2000年01月01日*/
	public final static int SHORT_DATEFORMAT_CN = 3;
	/**长日期中文格式,2000年01月01日01:01:01*/
	public final static int LONG_DATEFORMAT_CN = 4; 
	/**带星期的日期中文格式,2000年01月01日 星期一*/
	public final static int WEEK_DATEFORMAT_CN = 5;
	/**月日格式,02月03日*/
	public final static int MONTH_DAY_DATEFORMAT_CN = 6;
	
	/**
	 * 将yyyy-MM-dd HH:mm:ss转换为yyyyMMddHHmmss格式字符串
	 * @param dt    字符串
	 * @return      转换结果字符串
	 */
	public static String formatDatetime(String dt) {
		if (StringUtil.isEmpty(dt)) {return "";}
		return dt.replaceAll("[-: ]", "");
	}
	
	/**
	 * 将日期转换为yyyy-MM-dd HH:mm:ss格式字符串
	 * @param dt	日期对象
	 * @return		转换结果字符串
	 */
	public static String formatDatetime(Date dt){
		return dfDatetime.format(dt);
	}
	/**
	 * 将当前日期转换为yyyy-MM-dd HH:mm:ss格式字符串
	 * @return		转换结果字符串
	 */
	public static String formatDatetime(){
		return dfDatetime.format(new Date());
	}
	/**
     * 将指定String类型日期转换成指定的日期格式
     * @param strDate 字符串日期  格式: yyyy-MM-dd HH:mm:ss
     * @param pattern 日期格式
     * @return 转换结果字符串
     */
    public static String formatDatetime(String strDate, String pattern){
	    try {
		    Date date = dfDatetime.parse(strDate);
		    return formatDatetime(date,pattern);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
    }
	/**
	 * 将日期转换为yyyy-MM-dd格式字符串
	 * @param dt	日期对象
	 * @return		转换结果字符串
	 */
	public static String formatDate(Date dt){
		return dfDate.format(dt);
	}
	/**
	 * 将当前日期转换为yyyy-MM-dd格式字符串
	 * @return		转换结果字符串
	 */
	public static String formatDate(){
		return dfDate.format(new Date());
	}
	/**
	 * 将日期转换成参数pattern指定的格式
	 * @param dt
	 * @param pattern
	 * @return
	 */
	public static String formatDatetime(Date dt,String pattern){
		DateFormat dfDatetime = new SimpleDateFormat(pattern);
		return dfDatetime.format(dt);
	}
	/**
	 * 将当前日期转换成参数pattern指定的格式
	 * @param dt
	 * @param pattern
	 * @return
	 */
	public static String format(String pattern){
		DateFormat dfDatetime = new SimpleDateFormat(pattern);
		return dfDatetime.format(new Date());
	}
	/**校验所给日期是否合法,日期格式要求为:yyyyMMdd*/
	public static boolean checkDate(String date) {
		String eL = "^(\\d{4})(([0][13578](([0][1-9])|([12][0-9])|([3][01])))|([1][02](([0][1-9])|([12][0-9])|([3][01])))|([0][2469](([0][1-9])|([12][0-9])|([3][0])))|(11(([0][1-9])|([12][0-9])|([3][0]))))"; 
		Pattern p = Pattern.compile(eL);
		Matcher m = p.matcher(date);
		if(!m.matches()){
			return false;
		}
		int year = Integer.parseInt(date.substring(0,4));
		int month = Integer.parseInt(date.substring(4,6));
		int day = Integer.parseInt(date.substring(6));
		if(month == 2){
			if(year % 4 == 0 && year % 100 != 0
					|| (year % 100 == 0 && year % 400 == 0)){	//闰年
				if(day > 29){
					return false;
				}
			}else{
				if(day > 28){
					return false;
				}
			}
		}
		return true;
	}
	/**
	 * 将Julian Day 格式化为通用日期格式:yyyyMMdd
	 * @param julianDay 表示当前年份的第多少天
	 * @return
	 */
	public static String formatJulianDay(int julianDay){
		String dateStr = null;
		Calendar calendar = Calendar.getInstance();
		int currJulianDay = calendar.get(Calendar.DAY_OF_YEAR);
		if(Math.abs(currJulianDay - julianDay) > 350){//如果当前时间与所给参数时间相差太大,则做调整
			if(currJulianDay > julianDay){
				calendar.set(calendar.get(Calendar.YEAR) + 1, 0, 1,0,0,0);//当前年1月1日
			}else{
				calendar.set(calendar.get(Calendar.YEAR) - 1, 0, 1,0,0,0);//当前年1月1日
			}
		}else{
			calendar.set(calendar.get(Calendar.YEAR), 0, 1,0,0,0);//当前年1月1日
		}
		
		calendar.add(Calendar.DAY_OF_YEAR, julianDay - 1);
		
		dateStr = formatDate(calendar.getTime());
		return dateStr;
	} 
	/**
	 * 将Julian Day 格式化为通用日期格式:yyyyMMdd
	 * @param julianDay 表示当前年份的第多少天
	 * @return
	 */
	public static String formatJulianDay(int julianDay,int year){
		String dateStr = null;
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, 0, 1,0,0,0);//当前年1月1日
		calendar.add(Calendar.DAY_OF_YEAR, julianDay - 1);
		dateStr = formatDate(calendar.getTime());
		return dateStr;
	} 
	/**
	 * 将Julian Day 格式化为通用日期格式:yyyyMMdd
	 * @param julianDay 格式:YYDDD 年+julian day
	 * @return
	 */
	public static String formatJulianDay(String yyJulianDay){
		String dateStr = null;
		int year = Integer.parseInt("20" + yyJulianDay.substring(0,2));
		int julianDay = Integer.parseInt(yyJulianDay.substring(2,5));
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, 0, 1,0,0,0);//当前年1月1日
		calendar.add(Calendar.DAY_OF_YEAR, julianDay - 1);
		dateStr = formatDate(calendar.getTime());
		return dateStr;
	}

	public static String getDateWithFormat(int dateFormat){
		return getDateWithFormat(dateFormat,null);
	}
	/**
     * 提取当前时间,并格式化后返回
     * @param dateFormat 日期格式,參考DateUtil的常量定义,如DateUtil.SHORT_DATEFORMAT
     * @param date 指定要格式化的日期,如果传null,则取当前日期
     * @return stringDate 日期字符串
     */
    public static String getDateWithFormat(int dateFormat,Date date){
        String stringDate = "";
        String sMon = null;
        String sDay = null;
        String sHour = null;
        String sMinute = null;
        String sSecond = null;
        if (dateFormat == 0){
        	dateFormat = DateUtil.LONG_DATEFORMAT;
        }
        Calendar calendar = Calendar.getInstance();
        if(date != null){
        	 calendar.setTime(date);
        }
        int year	= calendar.get(Calendar.YEAR);
        int month	= calendar.get(Calendar.MONTH)+1;
        int day		= calendar.get(Calendar.DATE);
        int hours	= calendar.get(Calendar.HOUR_OF_DAY);
        int minute	= calendar.get(Calendar.MINUTE);
        int seconds	= calendar.get(Calendar.SECOND);
        int weekday = calendar.get(Calendar.DAY_OF_WEEK);
        
        sMon	= (month < 10?	"0"+month:String.valueOf(month));
        sDay	= (day < 10?	"0"+day:String.valueOf(day));
        sHour	= (hours < 10?	"0"+hours:String.valueOf(hours));
        sMinute = (minute < 10?	"0"+minute:String.valueOf(minute));
        sSecond = (seconds < 10?"0"+seconds:String.valueOf(seconds));
        
		if (dateFormat == DateUtil.SHORT_DATEFORMAT) {
			stringDate = year + "-" + sMon + "-" + sDay;
		} else if (dateFormat == DateUtil.LONG_DATEFORMAT) {
			stringDate = year + "-" + sMon + "-" + sDay + " " + sHour + ":" + sMinute + ":" + sSecond;
		} else if (dateFormat == DateUtil.SHORT_DATEFORMAT_CN){
			stringDate = year + "年" + sMon + "月" + sDay + "日";
		} else if (dateFormat == DateUtil.LONG_DATEFORMAT_CN){
			stringDate = year + "年" + sMon + "月" + sDay + "日 " + sHour + ":" + sMinute + ":" + sSecond;
		} else if (dateFormat == DateUtil.WEEK_DATEFORMAT_CN){
			stringDate = year + "年" + sMon + "月" + sDay + "日 " + toWeekDayStr(weekday);
		} else if (dateFormat == DateUtil.MONTH_DAY_DATEFORMAT_CN){
			stringDate = sMon + "月" + sDay + "日";
		}
		return stringDate;
    }
    
	/*
	 * 名称:toWeekDayStr 描述:把int型的星期转换成String
	 * 
	 * @param weekday int型的星期
	 * 
	 * @return 中文String星期
	 */
	public static String toWeekDayStr(int weekday) {
		switch (weekday) {
		case 1:
			return "星期天";
		case 2:
			return "星期一";
		case 3:
			return "星期二";
		case 4:
			return "星期三";
		case 5:
			return "星期四";
		case 6:
			return "星期五";
		case 7:
			return "星期六";
		default:
			return "";
		}
	}
	/**
	 * 将yyyy-MM-dd HH:mm:ss格式字符串转为日期
	 * @param dateString 格式:yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static Date stringToDate(String dateString) {
		Date date = null;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			date = sdf.parse(dateString);
		} catch (Exception e) {
			date = null;
			System.out.println(e);
		}
		return date;
	}
	
	/**
	 * 名称:turnDateToSqlDate 描述:把指定日期转换成sql.Date格式
	 * @param date 原指定日期
	 * @return newDate sql.Date格式日期
	 */
	public static java.sql.Date dateToSqlDate(Date date) {
		if (date == null){
			date = new Date();
		}
		return new java.sql.Date(date.getTime());
	}
	
	 /**
     * 获取指定日期N天后的日期
     * @param dateStr 格式:yyyy-MM-dd HH:mm:ss
     * @param intDays
     * @return
     */
    public static Date getNDayAfterDate(String dateStr,int intDays){
    	 Date date = stringToDate(dateStr);
	   	 Calendar nowTime = Calendar.getInstance();
	   	 nowTime.setTime(date);
	   	 nowTime.add(Calendar.DAY_OF_MONTH, intDays);
	   	 return nowTime.getTime();
    }
    /**
     * 获取指定日期N天后的日期串
     * @param dateStr 格式:yyyy-MM-dd HH:mm:ss
     * @param intDays
     * @return
     */
    public static String getNDayAfterDateStr(String dateStr,int intDays){
    	 Date date = stringToDate(dateStr);
	   	 Calendar nowTime = Calendar.getInstance();
	   	 nowTime.setTime(date);
	   	 nowTime.add(Calendar.DAY_OF_MONTH, intDays);
	   	 return formatDatetime(nowTime.getTime());
    }
    
    /**
     * 获取指定日期N天后的日期串
     * @param dateStr 格式:yyyy-MM-dd HH:mm:ss
     * @param intDays
     * @return
     */
    public static String getNMonthAfterDateStr(String dateStr,int intMonths){
    	 Date date = stringToDate(dateStr);
	   	 Calendar nowTime = Calendar.getInstance();
	   	 nowTime.setTime(date);
	   	 nowTime.add(Calendar.MONTH, intMonths);
	   	 return formatDatetime(nowTime.getTime());
    }
	/**
	 * @Title dateCalculate
	 * @Description 日期加减
	 * @param targetDate 原时间
	 * @param dateType 计算类型（1:年份  2:月份  3:周  5:天  10:小时  12:分钟  13:秒  14:毫秒）
	 * @param dateInt 加减的数量
	 * @throws
	 * @author mrf
	 * @date 2014年9月24日 下午5:23:47
	 */
	public static Date dateCalculate(Date targetDate, int dateType, int dateInt) {
		Calendar calendar=Calendar.getInstance();
		calendar.setTime(targetDate);
		calendar.set(dateType, calendar.get(dateType) + dateInt);
		return calendar.getTime();
	}
	/***
	 * 计算两个日期相差月份
	 * @param start
	 * @param end
	 * @return
	 */
	public static int getMonthDiff(Date start, Date end) {
		if (start.after(end)) {
			Date t = start;
			start = end;
			end = t;
		}
		Calendar startCalendar = Calendar.getInstance();
		startCalendar.setTime(start);

		Calendar endCalendar = Calendar.getInstance();
		endCalendar.setTime(end);

		Calendar temp = Calendar.getInstance();
		temp.setTime(end);
		temp.add(Calendar.DATE, 1);

		int year = endCalendar.get(Calendar.YEAR) - startCalendar.get(Calendar.YEAR);
		int month = endCalendar.get(Calendar.MONTH) - startCalendar.get(Calendar.MONTH);

		if ((startCalendar.get(Calendar.DATE) == 1)
				&& (temp.get(Calendar.DATE) == 1)) {
			return year * 12 + month + 1;
		} else if ((startCalendar.get(Calendar.DATE) != 1)
				&& (temp.get(Calendar.DATE) == 1)) {
			return year * 12 + month;
		} else if ((startCalendar.get(Calendar.DATE) == 1)
				&& (temp.get(Calendar.DATE) != 1)) {
			return year * 12 + month;
		} else {
			return (year * 12 + month - 1) < 0 ? 0 : (year * 12 + month);
		}
	}
    
	public static void main(String[] args){
		
		//System.out.println(formatDatetime("2015-09-01 14:21:11"));
		
		//System.out.println(DateUtil.formatDatetime(DateUtil.formatDatetime()));
		//int code = RandomUtils.nextInt(13);
		//System.out.println(code);
		
		//System.out.println(formatDatetime("2015-09-01 14:21:11", "MMddhhmmss"));
//		System.out.println(checkDate("2000113a1"));
//		System.out.println(formatJulianDay(3));
		System.out.println(getNMonthAfterDateStr("2015-08-14 23:02:34",35));
//		java.sql.Date d = dateToSqlDate(new Date());
//		System.out.println(d.toLocaleString());
//		
//		Date date = stringToDate("2015-08-14 23:02:34");
//		System.out.println(date.toLocaleString());
//		
//		System.out.println(getDateWithFormat(DateUtil.WEEK_DATEFORMAT_CN));
//		System.out.println(formatDatetime());
	}

}
